<?php
// @formatter:off
/**
 * @file WCSearchItems.php
 * @author Alejandro Dario Simi
 * @date $Date: 2013-07-18 22:13:05 +0000 (Thu, 18 Jul 2013) $
 *
 * $Id: WCSearchItems.php 97 2013-07-18 22:13:05Z daemonraco@gmail.com $
 * $URL: http://wcomix.googlecode.com/svn/tags/wcomix-1.0.0.2/includes/search/WCSearchItems.php $
 */
// @formatter:on

require_once dirname(__FILE__)."/WCSearchItems.php";

/**
 * @abstract
 * @class WCSearchItem This class represents in a generic way, an item found by a
 * search engine.
 */
abstract class WCSearchItem {
	/**
	 * @var WCGroup Pointer for the group where this item belongs.
	 */
	protected $_group = null;
	/**
	 * @param mixed[string] This is an associative array that hold all the
	 * information of current item. Its structure looks like this:
	 * @code
	 * Array(
	 *	"id"	=> int,
	 *	"words"	=> Array(),
	 *	"factors" => Array(
	 *		"e-words"	=> int
	 *		"p-words"	=> int
	 *		"hits"		=> int
	 *		"type"		=> int
	 *	)
	 * )
	 * @endcode
	 */
	protected $_info = null;
	/**
	 * @var string Identification hash id.
	 */
	protected $_hash = false;
	/**
	 * @var boolean This flag indicates if there's any problem with the
	 * current item.
	 */
	protected $_broken = true;
	/**
	 * @var int This is the unique ID of the represented item
	 */
	protected $_id = -1;
	/**
	 * @var string This is the name of the represented item.
	 */
	protected $_name = "unknown";
	/**
	 * @var string This is a extended version of the name.
	 */
	protected $_fullName = "unknown";
	/**
	 * Class constructor.
	 *
	 * @param WCGroup $group Pointer for the group where this item belongs.
	 * @param mixed[string] $info Item's information.
	 * @param string $hash Hash code to identify the item.
	 */
	public function __construct(WCGroup &$group, $info, $hash) {
		//
		// Saving group's pointer.
		$this->_group = $group;
		//
		// Saving item information.
		$this->_info = $info;
		//
		// Saving hash code.
		$this->_hash = $hash;
		//
		// Calling the specific loader.
		$this->loadExtraInfo();
	}
	//
	// Public methods.
	/**
	 * This method allows to access the amount of sub-elements of current
	 * item.
	 *
	 * @return int Returns the count of sub-elements.
	 */
	public function count() {
		//
		// Unless redefined, it always returns false.
		return false;
	}
	/**
	 * This method returns a relevance factor for this item based on search
	 * results.
	 *
	 * @return string Returns a string with the item's factor.
	 */
	public function factor() {
		$factor = $this->_info["factors"]["e-words"];
		$factor .= ".".$this->_info["factors"]["p-words"];
		$factor .= ".".$this->_info["factors"]["hits"];
		$factor .= ".".$this->_info["factors"]["type"];
		return $factor;
	}
	/**
	 * This method allows to access the represented object's extended name.
	 *
	 * @return string Returns the object's extended name.
	 */
	public function fullName() {
		return $this->_fullName;
	}
	/**
	 * This method allows to know if current item has preview images.
	 *
	 * @return boolean Returns true when item has previews.
	 */
	public function hasPreviews() {
		//
		// Unless redefined, it always returns false.
		return false;
	}
	/**
	 * This method allows to know how many times this item was found when
	 * searching for it.
	 *
	 * @return int Returns the times this item was found on its search.
	 */
	public function hits() {
		return $this->_info["factors"]["hits"];
	}
	/**
	 * This method allows to know if there's any problem with the current
	 * item.
	 *
	 * @return boolean Returns true when there are issues.
	 */
	public function isBroken() {
		return $this->_broken;
	}
	/**
	 * This method allows to get a link for the current item. This method is
	 * useful for interfaces when the try to access this item.
	 *
	 * @return string Returns a link for the item.
	 */
	public function link() {
		//
		// Unless redifined, this method always triggers a error.
		trigger_error(__CLASS__."::".__FUNCTION__."(): Subclass Responsibility.", E_USER_ERROR);
		return "";
	}
	/**
	 * This method allows to access the represented object's name.
	 *
	 * @return string Returns the object's name.
	 */
	public function name() {
		return $this->_name;
	}
	/**
	 * This method allows to access item's previews.
	 *
	 * @return string[] Returns a list of images URIs.
	 */
	public function previews() {
		//
		// Unless redefined, this method always returns an empty list.
		return array();
	}
	/**
	 * This method allows to know the list of words used to search and find
	 * this item.
	 *
	 * @return string[] Returns a list of words.
	 */
	public function searchPattern() {
		return $this->_info["words"];
	}
	/**
	 * This method allows to know item's type.
	 *
	 * @return string Returns a string with the item's type.
	 */
	public function type() {
		//
		// Unless redefined, this method always returns an empty string.
		return "";
	}
	//
	// Protected methods.
	/**
	 * This method is the one in charge of loading all the required extra
	 * data of this item before it can be used.
	 */
	protected function loadExtraInfo() {
		//
		// Unless redefined, this method always triggers a error.
		trigger_error(__CLASS__."::".__FUNCTION__."(): Subclass Responsibility.", E_USER_ERROR);
	}
}

/**
 * class WCSearchItemCX This class represents a comic item found by a search
 * engine.
 */
class WCSearchItemCX extends WCSearchItem {
	/**
	 * @var WCComic Pointer to the represented comic.
	 */
	protected $_comic = false;
	//
	// Public methods.
	/**
	 * This method allows to know if current item has preview images.
	 *
	 * @return boolean Returns true when item has previews.
	 */
	public function hasPreviews() {
		return true;
	}
	/**
	 * This method allows to get a link for the current item. This method is
	 * useful for interfaces when the try to access this item.
	 *
	 * @return string Returns a link for the item.
	 */
	public function link() {
		return "?action=".WC_ACTION_COMIC_SHOW."&group={$this->_comic->group}&comic={$this->_comic->id}";
	}
	/**
	 * This method allows to access comic's previews.
	 *
	 * @return string[] Returns a list of images URIs.
	 */
	public function previews() {
		return array($this->_comic->previewUri());
	}
	/**
	 * This method allows to know item's type.
	 *
	 * @return string Returns a string with the item's type.
	 */
	public function type() {
		return "Comic";
	}
	//
	// Protected methods.
	/**
	 * This method is the one in charge of loading all the required extra
	 * data of this item before it can be used.
	 */
	protected function loadExtraInfo() {
		//
		// Loading global pointers.
		global $wcComicsHolder;
		//
		// Getting comic from its holder.
		$this->_comic = $wcComicsHolder->item($this->_info["id"], $this->_group);
		//
		// Checking obtained comic.
		if($this->_comic && $this->_comic->ok()) {
			//
			// At this point, item is not broken.
			$this->_broken = false;
			//
			// Saving item's id.
			$this->_id = $this->_comic->id;
			//
			// Saving item's name
			$this->_name = $this->_comic->name();
			//
			// Generating a item's name.
			$this->_fullName = "{$this->_comic->name()} at {$this->_comic->directory()->name}";
		} else {
			//
			// At this point, comic has some kind of issue, therefore
			// its pointer remains false.
			$this->_comic = false;
		}
	}
}

/**
 * class WCSearchItemDI This class represents a directory item found by a search
 * engine.
 */
class WCSearchItemDI extends WCSearchItem {
	/**
	 * @var WCDirectory Pointer to the represented directory.
	 */
	protected $_directory = false;
	//
	// Public methods.
	/**
	 * This method allows to access the amount of sub-elements of current
	 * item.
	 *
	 * @return int Returns the count of comics in the directory.
	 */
	public function count() {
		//
		// Setting a default value to be returned.
		$out = false;
		//
		// Checking item's status.
		if(!$this->isBroken()) {
			//
			// Getting comics count.
			$out = $this->_directory->count;
		}
		//
		// Returning count's result.
		return $out;
	}
	/**
	 * This method allows to know if current item has preview images.
	 *
	 * @return boolean Returns true when item has previews.
	 */
	public function hasPreviews() {
		return true;
	}
	/**
	 * This method allows to get a link for the current item. This method is
	 * useful for interfaces when the try to access this item.
	 *
	 * @return string Returns a link for the item.
	 */
	public function link() {
		return "?action=".WC_ACTION_DIRECTORY_SHOW."&group={$this->_directory->group}&directory={$this->_directory->id}";
	}
	/**
	 * This method allows to access directory's previews.
	 *
	 * @return string[] Returns a list of images URIs.
	 */
	public function previews() {
		return $this->_directory->previews();
	}
	/**
	 * This method allows to know item's type.
	 *
	 * @return string Returns a string with the item's type.
	 */
	public function type() {
		return "Directory";
	}
	//
	// Protected methods.
	/**
	 * This method is the one in charge of loading all the required extra
	 * data of this item before it can be used.
	 */
	protected function loadExtraInfo() {
		//
		// Loading global pointers.
		global $wcDirectoriesHolder;
		//
		// Getting directory from its holder.
		$this->_directory = $wcDirectoriesHolder->item($this->_info["id"], $this->_group);
		//
		// Checking obtained directory.
		if($this->_directory) {
			//
			// At this point, item is not broken.
			$this->_broken = false;
			//
			// Saving item's id.
			$this->_id = $this->_directory->id;
			//
			// Saving item's name
			$this->_name = $this->_directory->name;
			//
			// Generating a item's name.
			$this->_fullName = $this->_directory->name;
		} else {
			//
			// At this point, directory has some kind of issue,
			// therefore its pointer remains false.
			$this->_directory = false;
		}
	}
}

/**
 * class WCSearchItemTA This class represents a tag item found by a search
 * engine.
 */
class WCSearchItemTA extends WCSearchItem {
	/**
	 * @var WCTag Pointer to the represented tag.
	 */
	protected $_tag = false;
	//
	// Public methods.
	/**
	 * This method allows to access the amount of sub-elements of current
	 * item.
	 *
	 * @return int Returns the count of comics in the tag.
	 */
	public function count() {
		//
		// Setting a default value to be returned.
		$out = false;
		//
		// Checking item's status.
		if(!$this->isBroken()) {
			//
			// Getting comics count.
			$out = $this->_tag->count;
		}
		//
		// Returning count's result.
		return $out;
	}
	/**
	 * This method allows to know if current item has preview images.
	 *
	 * @return boolean Returns true when item has previews.
	 */
	public function hasPreviews() {
		return true;
	}
	/**
	 * This method allows to get a link for the current item. This method is
	 * useful for interfaces when the try to access this item.
	 *
	 * @return string Returns a link for the item.
	 */
	public function link() {
		return "?action=".WC_ACTION_TAG_SHOW."&group={$this->_tag->group}&tag={$this->_tag->id}";
	}
	/**
	 * This method allows to access tag's previews.
	 *
	 * @return string[] Returns a list of images URIs.
	 */
	public function previews() {
		return $this->_tag->previews();
	}
	/**
	 * This method allows to know item's type.
	 *
	 * @return string Returns a string with the item's type.
	 */
	public function type() {
		return "Tag";
	}
	//
	// Protected methods.
	/**
	 * This method is the one in charge of loading all the required extra
	 * data of this item before it can be used.
	 */
	protected function loadExtraInfo() {
		//
		// Loading global pointers.
		global $wcTagsHolder;
		//
		// Getting tag from its holder.
		$this->_tag = $wcTagsHolder->item($this->_info["id"], $this->_group);
		//
		// Checking obtained tag.
		if($this->_tag) {
			//
			// At this point, item is not broken.
			$this->_broken = false;
			//
			// Saving item's id.
			$this->_id = $this->_tag->id;
			//
			// Saving item's name
			$this->_name = $this->_tag->name;
			//
			// Generating a item's name.
			$this->_fullName = $this->_tag->name;
		} else {
			//
			// At this point, tag has some kind of issue, therefore
			// its pointer remains false.
			$this->_tag = false;
		}
	}
}

/**
 * class WCSearchItemCL This class represents a collection item found by a search
 * engine.
 */
class WCSearchItemCL extends WCSearchItem {
	/**
	 * @var WCCollection Pointer to the represented collection.
	 */
	protected $_collection = false;
	//
	// Public methods.
	/**
	 * This method allows to access the amount of sub-elements of current
	 * item.
	 *
	 * @return int Returns the count of comics in the collection.
	 */
	public function count() {
		//
		// Setting a default value to be returned.
		$out = false;
		//
		// Checking item's status.
		if(!$this->isBroken()) {
			//
			// Getting comics count.
			$out = $this->_collection->count;
		}
		//
		// Returning count's result.
		return $out;
	}
	/**
	 * This method allows to know if current item has preview images.
	 *
	 * @return boolean Returns true when item has previews.
	 */
	public function hasPreviews() {
		return true;
	}
	/**
	 * This method allows to get a link for the current item. This method is
	 * useful for interfaces when the try to access this item.
	 *
	 * @return string Returns a link for the item.
	 */
	public function link() {
		return "?action=".WC_ACTION_COLLECTION_SHOW."&group={$this->_collection->group}&collection={$this->_collection->id}";
	}
	/**
	 * This method allows to access collection's previews.
	 *
	 * @return string[] Returns a list of images URIs.
	 */
	public function previews() {
		return $this->_collection->previews();
	}
	/**
	 * This method allows to know item's type.
	 *
	 * @return string Returns a string with the item's type.
	 */
	public function type() {
		return "Collection";
	}
	//
	// Protected methods.
	/**
	 * This method is the one in charge of loading all the required extra
	 * data of this item before it can be used.
	 */
	protected function loadExtraInfo() {
		//
		// Loading global pointers.
		global $wcCollectionsHolder;
		//
		// Getting collection from its holder.
		$this->_collection = $wcCollectionsHolder->item($this->_info["id"], $this->_group);
		//
		// Checking obtained collection.
		if($this->_collection) {
			//
			// At this point, item is not broken.
			$this->_broken = false;
			//
			// Saving item's id.
			$this->_id = $this->_collection->id;
			//
			// Saving item's name
			$this->_name = $this->_collection->name;
			//
			// Generating a item's name.
			$this->_fullName = $this->_collection->name;
		} else {
			//
			// At this point, collection has some kind of issue,
			// therefore its pointer remains false.
			$this->_collection = false;
		}
	}
}

/**
 * class WCSearchItemRL This class represents a rule item found by a search
 * engine.
 */
class WCSearchItemRL extends WCSearchItem {
	/**
	 * @var WCRule Pointer to the represented rule.
	 */
	protected $_rule = null;
	/**
	 * @var int This variable hold the number of actions belonging to this
	 * rule. 'false' means it is not yet calculated.
	 */
	protected $_count = false;
	//
	// Public methods.
	/**
	 * This method allows to access the amount of sub-elements of current
	 * item.
	 *
	 * @return int Returns the count of rule's actions.
	 */
	public function count() {
		//
		// Setting a default value to be returned.
		$out = false;
		//
		// Checking item's status.
		if(!$this->isBroken()) {
			//
			// Checking if the number of actions is calculated.
			if($this->_count === false) {
				//
				// Starting the count.
				$this->_count = 0;
				//
				// Counting each type.
				foreach($this->_rule->count() as $c) {
					$this->_count += $c;
				}
			}
			//
			// Getting actions count.
			$out = $this->_count;
		}
		//
		// Returning count's result.
		return $out;
	}
	/**
	 * This method allows to know if current item has preview images.
	 *
	 * @return boolean Returns true when item has previews.
	 */
	public function hasPreviews() {
		return false;
	}
	public function link($mobile = false) {
		return "?action=".WC_ACTION_RULE_SHOW."&group={$this->_rule->group}&rule={$this->_rule->id}";
	}
	/**
	 * This method allows to access rule's previews.
	 *
	 * @return string[] Returns a list of images URIs.
	 */
	public function previews() {
		return array();
	}
	/**
	 * This method allows to know item's type.
	 *
	 * @return string Returns a string with the item's type.
	 */
	public function type() {
		return "Rule";
	}
	//
	// Protected methods.
	/**
	 * This method is the one in charge of loading all the required extra
	 * data of this item before it can be used.
	 */
	protected function loadExtraInfo() {
		//
		// Loading global pointers.
		global $wcRulesHolder;
		//
		// Getting rule from its holder.
		$this->_rule = $wcRulesHolder->item($this->_info["id"], $this->_group);
		//
		// Checking obtained rule.
		if($this->_rule) {
			//
			// At this point, item is not broken.
			$this->_broken = false;
			//
			// Saving item's id.
			$this->_id = $this->_rule->id;
			//
			// Saving item's name
			$this->_name = $this->_rule->name;
			//
			// Generating a item's name.
			$this->_fullName = $this->_rule->name;
		} else {
			//
			// At this point, rule has some kind of issue, therefore
			// its pointer remains false.
			$this->_rule = false;
		}
	}
}
